/**
 * Copyright (C) 2012-2013 jumei, Inc.
 * MessageContext.java
 * 2015年6月25日
 */
package org.goface.rpc;

import io.netty.channel.Channel;

import java.util.HashMap;
import java.util.Map;

import org.goface.rpc.invoker.ServiceInvoker;
import org.goface.rpc.invoker.SpringBeanInvoker;

import com.goface.rpc.conf.ServiceConfigure;
import com.google.common.net.HostAndPort;
import com.google.common.util.concurrent.SettableFuture;

/**
 * @author jm110
 */
public class MessageContext {
    public static String MESSAGE_TYPE = "message_type";
    public static String MESSAGE_TYPE_REQUEST = "request";
    public static String MESSAGE_TYPE_REPLY = "reply";

    public static String CLIENT_CHANNEL = "client_channel";

    private Message message;
    private Map<String, Object> properties;
    private SettableFuture<Message> retFutre;
    

    /**
     * @return the properties
     */
    public Map<String, Object> getProperties() {
        return properties;
    }

    /**
     * @param properties
     *            the properties to set
     */
    public void setProperties(Map<String, Object> properties) {
        this.properties = properties;
    }

    /**
     * @return the ret
     */
    public SettableFuture<Message> getRetFuture() {
        return retFutre;
    }

    /**
     * @param ret
     *            the ret to set
     */
    public void setRetFuture(SettableFuture<Message> ret) {
        this.retFutre = ret;
    }

    /**
     * @return the message
     */
    public Message getMessage() {
        return message;
    }

    /**
     * @param message
     *            the message to set
     */
    public void setMessage(Message message) {
        this.message = message;
    }

    public boolean isAsyncInvok() {
        return "true".equals(this.properties.get(ServiceConfigure.SERVICE_CLIENT_ASYNC_INVOK));
    }

    public boolean isOneWay() {
        return Boolean.class.cast(this.properties.get(ServiceConfigure.SERVICE_CLIENT_OP_ONEWAY));

    }

    public HostAndPort getServiceAddress() {
        return HostAndPort.class.cast(this.properties.get(ServiceConfigure.SERVICE_CLIENT_SERVICE_ADDRESS));
    }

    public boolean isRequestMessage() {
        return MESSAGE_TYPE_REQUEST.equals(properties.get(MESSAGE_TYPE));
    }

    public boolean isReplytMessage() {
        return MESSAGE_TYPE_REPLY.equals(properties.get(MESSAGE_TYPE));
    }

    public String getClientServiceId() {
        return properties.get(ServiceConfigure.SERVICE_ID).toString();
    }

    public static MessageContext createRequest() {
        MessageContext messgeContext = new MessageContext();
        Map<String, Object> properties = new HashMap<>();
        properties.put(MESSAGE_TYPE, MESSAGE_TYPE_REQUEST);
        messgeContext.setProperties(properties);
        return messgeContext;
    }

    public static MessageContext createReply() {
        MessageContext messgeContext = new MessageContext();
        Map<String, Object> properties = new HashMap<>();
        properties.put(MESSAGE_TYPE, MESSAGE_TYPE_REPLY);
        messgeContext.setProperties(properties);
        return messgeContext;
    }

    public Channel getClientChannel() {
        return Channel.class.cast(properties.get(CLIENT_CHANNEL));
    }
    
	public ServiceInvoker getServiceInvoker() {
		Object invoker = properties.get(ServiceConfigure.SERVICE_INVOKER);
		if (invoker == null) {
			invoker = new SpringBeanInvoker();
		}
		return ServiceInvoker.class.cast(invoker);

	}
}
